import os
from collections import Counter
import pandas as pd
import jieba
from wordcloud import wordcloud


class TitleStatistical:
    def __init__(self):
        self.topic_list = []
        self.counter = {}
        self.topic_dict = {}
        self.my_BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        # csv_path：读取的csv文件(爬虫产物)
        self.csv_path = os.path.join(self.my_BASE_DIR, 'static', 'csv_collect', 'deep_articles.csv')
        # title_txt：标题 待分类文本
        self.title_txt = os.path.join(self.my_BASE_DIR, 'static', 'txt_collect', 'title_txt.txt')
        # 用于词云解析中文字体
        self.font_path = os.path.join(self.my_BASE_DIR, 'static', 'txt_collect', 'STXINGKA.TTF')
        # 词云图片路径
        self.word_cloud_png = os.path.join(self.my_BASE_DIR, 'static', 'picture', 'word_cloud.png')
        # first_selectTXT_path：用于制作jiaba自定义字典，可以往里面补充互联网词汇
        self.first_selectTXT_path = os.path.join(self.my_BASE_DIR, 'static', 'txt_collect', 'first_select.txt')
        # jiebaDirectTXT_path：从first_select.txt生成的可供程序运行的jieba自定义字典
        self.jiebaDirectTXT_path = os.path.join(self.my_BASE_DIR, 'static', 'txt_collect', 'jieba_directory.txt')
        # jieba停用词字典
        self.jieba_stop_dictionary = os.path.join(self.my_BASE_DIR, 'static', 'txt_collect',
                                                  'jieba_stop_dictionary.txt')

    def statistical(self):
        # 读取数据
        df = pd.read_csv(self.csv_path, sep=",", header=0, encoding="utf-8")

        # 清洗数据 生成目标待词频统计文本-------------做一次就好，为了快速响应api接口，先注释掉
        # 制作待分类文本
        # 保证每次都是生产出新的title_txt待分类文本
        # if os.path.exists(self.title_txt):
        #     os.remove(self.title_txt)
        # for i in range(len(df)):
        #     self.add_txt(df["title"][i])
        # ------------------------------------------------------------------------

        # 使用jieba统计词频，将统计结果在topic_dict
        self.extract_jieba()
        # print(self.topic_dict)

        # 绘制词云图
        w = wordcloud.WordCloud(font_path=self.font_path, width=1920, height=1080, max_words=200, font_step=1,
                                background_color="rgba(255, 255, 255, 0)", mode="RGBA")
        w.generate_from_frequencies(self.topic_dict)
        w.to_file(self.word_cloud_png)

        print('make wordCloud successfully!')

        # 直接做个字典，里面包含统计数据和图片url地址
        data = {
            "img_url": "http://localhost:8888/static/picture/word_cloud.png",
            # self.topic是可以传，在apifox里面也显示正常，但是在浏览器里就算使用undecodeURI也依旧错误。因此再次用打印的数据临时代替一下
            "title": {
                 '实现': 1013, '如何': 776, '使用': 774, '前端': 768, '开发': 517, 'Vue': 463, '技术': 402, 'js': 376,
                 '代码': 364, '项目': 356, '应用': 353, '组件': 345, '实践': 327, 'React': 305, '数据': 301,
                 '模型': 300, 'AI': 285, 'Java': 284, '原理': 270, 'Android': 268, '实战': 234, '学习': 233,
                 '优化': 229, '基于': 226, '问题': 224, 'JavaScript': 220, 'vue': 217, '工具': 216, '方法': 213,
                 '2023': 206, '开源': 205, '指南': 203, 'CSS': 198, '框架': 191, '云': 190, '入门': 190, '搭建': 189,
                 '详解': 188, '源码': 187, '面试': 185, 'Flutter': 185, '管理': 182, '团队': 182, '分析': 182,
                 '深入': 179, '设计': 176, '解析': 173, '插件': 169, '算法': 169, 'Spring': 166, '基础': 166,
                 '方案': 163, '为什么': 163, 'JS': 163, '简单': 160, 'Web': 160, '理解': 158, '发布': 157, '及': 157,
                 '系统': 157, '快速': 156, 'Python': 155, '效果': 150, '系列': 149, '部署': 146, '功能': 146,
                 '京东': 144, '模式': 144, 'iOS': 143, '配置': 140, '面试官': 138, '总结': 137, 'Go': 137, '文件': 137,
                 '技巧': 136, '探索': 134, 'API': 133, '知道': 132, '了解': 131, 'GPT': 131, '解决': 131, '构建': 128,
                 '数据库': 125, '🔥': 124, '动画': 122, 'ChatGPT': 119, '教程': 118, 'MySQL': 118, '封装': 118,
                 '函数': 118, '做': 117, '方式': 116, '处理': 116, '程序': 115, '自己': 115, '页面': 113, '性能': 113,
                 '图片': 113, '怎么': 112, '工作': 112, '生成': 112, '开发者': 111, '程序员': 109, '请求': 109,
                 '说': 108, '优雅': 108, 'OpenAI': 107, '笔记': 106, '"': 105, '编程': 103, '&': 101, '支持': 101,
                 '动态': 101, '分享': 100, '掌握': 100, '接口': 99, '自定义': 99, 'Code': 98, 'Node': 97, '可以': 96,
                 '提升': 95, 'Redis': 95, '就': 93, 'HarmonyOS': 93, '性能优化': 93, '服务': 93, '类型': 93, '鸿蒙': 92,
                 '架构': 92, '语言': 92, '场景': 91, '常用': 91, '🚀': 90, '最佳': 90, '进阶': 89, 'SpringBoot': 87,
                 '进行': 87, '要': 87, '平台': 85, '一文': 84, '缓存': 84, '浏览器': 83, '以及': 83,
                 '区别': 82, '机制': 82, '引擎': 82, 'Git': 82, '安装': 82, '测试': 82, '为': 81, 'Rust': 81,
                 '面试题': 81
            }
        }

        return data

    # 写入title.txt作为待分类文本，需要被遍历调用
    def add_txt(self, topic):
        # 清洗数据
        # 给定的时间字符串可能为NOTFOUND或者空字符
        if "" != topic and "NOTFOUND" != topic:
            # 先遍历全部category写入txt文件
            with open(self.title_txt, 'a', encoding="utf-8") as f:
                f.write(topic.replace("\n", ""))

    # 利用jieba字典，统计词频
    def extract_jieba(self):
        # 使用自己定制的jieba字典库
        jieba.load_userdict(self.jiebaDirectTXT_path)

        # 使用自己定制的jieba停用词字典
        # 结巴似乎没法直接加载停用词
        stop_words_list = []
        with open(self.jieba_stop_dictionary, 'r', encoding="utf-8") as f:
            for line in f:
                stop_words_list.append(line.rstrip("\n"))  # 删除单词

        # 这是你的字符串
        with open(self.title_txt, 'r', encoding="utf-8") as f:
            topic_txt_string = f.read().rstrip("\n")

            # 使用jieba进行分词
            words = jieba.lcut(topic_txt_string, )

            # 将停用词list列表转换为集合
            stopwords_set = set(stop_words_list)

            # 使用列表推导式过滤掉分词列表中的停用词，返回一个新的分词列表
            words_without_stopwords = [word for word in words if word not in stopwords_set]

            # 使用Counter统计每个词语出现的次数
            temp_counter = Counter(words_without_stopwords)

            # print(temp_counter)
            # 打印结果
            for word, count in temp_counter.items():
                # print(f"词语'{word}'出现的次数：{count}")

                # 过滤错误分词数据
                if word == "." or word == "-" or word == "/" or word == "·" or word == "6" or word == " ":
                    continue
                else:
                    self.counter[word] = count

            # 使用sorted()函数和lambda函数，按照字典的值排序
            # sorted()函数返回一个由键值对组成的列表
            sorted_list = sorted(self.counter.items(), key=lambda x: x[1], reverse=True)

            # 使用dict()函数，将列表转换为一个新的字典
            self.topic_dict = dict(sorted_list)


# 以脚本方式启动
if __name__ == "__main__":
    # 捕捉异常错误
    try:
        ts = TitleStatistical()
        ts.statistical()
    except Exception as e:
        print("错误:", e)
